package com.dnndo.web.controller.system;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dnndo.common.constant.RedisConstant;
import com.dnndo.common.core.domain.AjaxResult;
import com.dnndo.common.core.domain.R;
import com.dnndo.common.core.domain.entity.SysUser;
import com.dnndo.common.core.domain.model.ForgetPwdDTO;
import com.dnndo.common.core.domain.model.LoginBody;
import com.dnndo.common.core.domain.model.LoginUser;
import com.dnndo.common.core.redis.RedisCache;
import com.dnndo.common.utils.SecurityUtils;
import com.dnndo.framework.web.service.SysLoginService;
import com.dnndo.framework.web.service.SysPermissionService;
import com.dnndo.framework.web.service.TokenService;
import com.dnndo.system.domain.vo.LoginVO;
import com.dnndo.system.service.IMenuService;
import com.dnndo.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Set;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private IMenuService menuService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    /**
     * 密码登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    //完成 数据源区分
    @PostMapping("/login")
    public R<LoginVO> login(@RequestBody LoginBody loginBody)

    {
        System.out.println("loginBody.get = " + loginBody.getCode());
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        return R.ok(new LoginVO(token));
    }
    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    //完成 数据源区分
    @GetMapping("/getInfo")
    public R<SysUser> getInfo()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        return R.ok(user);
    }

    /**
     * 获取权限信息
     */
    @GetMapping("/getPermissions")
    public AjaxResult getPermissions()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        // 权限集合 完成数据源区分
        Set<String> permissions = permissionService.getMenuPermission(user);
        if (!loginUser.getPermissions().equals(permissions))
        {
            loginUser.setPermissions(permissions);
            tokenService.refreshToken(loginUser);
        }
        JSONObject result = new JSONObject();
        result.put("permissions", loginUser.getPermissions());
        return AjaxResult.success(result);
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    //完成 数据源区分
    @GetMapping("/getRouters")
    public AjaxResult getRouters()
    {
        return AjaxResult.success(menuService.getTree());
    }

    /**
     * 忘记密码
     */
    @PostMapping("/forgetPwd")
    public R<?> forgetPwd(@RequestBody ForgetPwdDTO dto) {
        //查询用户是否存在
        long count = userService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getPhonenumber, dto.getPhone())
                .eq(SysUser::getDelFlag, 0));
        if (count == 0) {
            return R.fail("用户不存在");
        }
        //验证短信验证码
        Boolean hasKey = redisCache.hasKey(RedisConstant.SMS_CODE_KEY + dto.getPhone());
        if (!hasKey) {
            return R.fail("验证码错误");
        } else {
            String smsCode = redisCache.getCacheObject(RedisConstant.SMS_CODE_KEY + dto.getPhone());
            if (!dto.getSmsCode().equals(smsCode)) {
                return R.fail("验证码错误");
            } else {
                redisCache.deleteObject(RedisConstant.SMS_CODE_KEY + dto.getPhone());
                redisCache.deleteObject(RedisConstant.SMS_CODE_COUNT_KEY + dto.getPhone());
            }
        }
        //修改密码
        boolean b = userService.update(new LambdaUpdateWrapper<SysUser>()
                .eq(SysUser::getPhonenumber, dto.getPhone())
                .set(SysUser::getPassword, SecurityUtils.encryptPassword(dto.getPassword())));
        if (!b) {
            return R.fail("修改失败");
        } else {
            return R.ok();
        }
    }
}
